/**
 * 2009-12-15 下午04:37:50 
 * esignature
 * com.smc.signature
 * JksCertificate
 */
package com.smc.signature;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;

/**
 * @author chenheng
 * @version 0.0.1
 */
public class CertificateImpl extends AbstractCertificate {
	/**
	 * @param storeType
	 * @param keyStore
	 * @param storePass
	 * @param keyAlg
	 * @param sigAlg
	 * storeType可以为jks;
	 * 当keyAlg = DSA 时，sigAlg = SHA1withDSA ;
	 * 当keyAlg = RSA 时，sigAlg = MD5withRSA ; 
	 */
	public CertificateImpl(String storeType,String keyStore,String storePass,String keyAlg,String sigAlg,String shellScriptPath ) {
		this.storeType = storeType ;
		this.keyStore = keyStore ;
		this.storePass = storePass ;
		this.keyAlg = keyAlg ;
		this.sigAlg = sigAlg ;
		this.shellScriptPath = shellScriptPath ;
	}
	@Override
	public void certRequest(String alias) {
		StringBuffer sb = new StringBuffer();
		sb.append(" keytool ");
		sb.append(" -certreq ");
		sb.append(" -alais ");
		sb.append(alias);
		sb.append(" -sigalg ");
		sb.append(this.sigAlg);
		sb.append(" -file ");
		sb.append("smcCertReq.csr");
		sb.append(" -keypass ");
		sb.append("smc");
		sb.append(" -keystore ");
		sb.append(this.keyStore);
		sb.append(" -storepass ");
		sb.append(this.storePass);
		sb.append(" -storetype ");
		sb.append(this.storeType);
		
		Runtime rt = Runtime.getRuntime();
		Process p = null ;
		try {
			p = rt.exec(sb.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void certSelf(String alias) {
		StringBuffer sb = new StringBuffer();
		sb.append("keytool ");
		sb.append("-selfcert ");
		sb.append("-alias ");
		sb.append(alias);
		sb.append(" -dname ");
		sb.append("\"");
		sb.append("CN=steve,OU=develop,O=securemedicalchart,L=Los Angeles,S=California,C=US");
		sb.append("\"");
		sb.append(" -validity ");
		sb.append("1095");
		sb.append(" -keypass ");
		sb.append("123456");
		sb.append(" -sigalg ");
		sb.append(this.sigAlg);
		sb.append(" -keystore ");
		sb.append(this.keyStore);
		sb.append(" -storepass ");
		sb.append("123456");
		sb.append(" -storetype ");
		sb.append(this.storeType);
		
		Runtime rt = Runtime.getRuntime();
		Process p = null ;
		try {
			p = rt.exec(sb.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void genkey(String alias,String dname,String keyalg,String keysize,String sigalg,String validity,String keypass) {
		Runtime rt = Runtime.getRuntime();
		Process p = null ;
		try {
			String[] cmd = {"/bin/sh",shellScriptPath + "keytool_genkey.sh",alias,keyalg,keysize,dname,validity,keypass,storePass,keyStore};
			p = rt.exec(cmd);
//			InputStream is = p.getErrorStream();	
//			InputStream is = p.getInputStream();
//			InputStreamReader isr = new InputStreamReader(is);
//			BufferedReader br = new BufferedReader(isr);
//			String line = null ;
//			while ( (line = br.readLine()) != null) {
//				System.out.println(line);
//			}
//			int exitValue = p.waitFor();
//			System.out.println(exitValue);
		} catch ( IOException e) {
			e.printStackTrace();
		} 
	}
	public boolean sign(String[] params) {
		String alias = params[0];
		String keypass = params[1];
		String src = params[2];
		String dist = params[3];
		String reason = params[4];
		String location = params[5];
		boolean flag = false ;
		try {
			KeyStore keyStore = KeyStore.getInstance(storeType);
			keyStore.load(new FileInputStream(this.keyStore), storePass.toCharArray());
			PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias,
					keypass.toCharArray());
			Certificate[] chain = keyStore.getCertificateChain(alias);
			PdfReader pdfReader = new PdfReader(src);
			FileOutputStream fout = new FileOutputStream(dist);
			PdfStamper pdfStamper = PdfStamper.createSignature(pdfReader, fout,
					'\0');
			PdfSignatureAppearance sap = pdfStamper.getSignatureAppearance();
			sap.setCrypto(privateKey, chain, null,
					PdfSignatureAppearance.WINCER_SIGNED);
			if (reason != null) {
				sap.setReason(reason);
			}
			if (location != null) {
				sap.setLocation(location);
			}
			//sap.setVisibleSignature(new Rectangle(100,100, 200, 200), pdfReader.getNumberOfPages(), null);
			pdfStamper.close();
			flag = true ;
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CertificateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return flag ;
	}
	
	public void certDelete(String alias) {
		Runtime runtime = Runtime.getRuntime();
		Process p = null ;
		String[] cmd = {"/bin/sh",shellScriptPath + "keytool_delete.sh",alias,keyStore,storePass};
		try {
			p = runtime.exec(cmd);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}
